import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import javax.swing.JPanel;

/**
 * Copyright (C) 2013  Arun Lee & Bryce Nagareda
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Draw the dial face for horizontal sundial, 
 *  everything should be in scale to the given radius
 * @author Arun Lee
 */
public class DrawHDialFace extends JPanel implements Printable{
	/**Serial verion uid*/
	private static final long serialVersionUID = 1L;
	private double[] hourlines;
	private boolean south;
	private String timezone = " ";
	private int length = 1;
	private int height = 500;
	private int width = 700;
	
	/**
	 * initialized variables for drawing hour lines.
	 * 
	 * @param hrl hour lines
	 * @param S south
	 * @param tz timezone
    * @param radius radius
	 */
	public DrawHDialFace(double[] hrl, boolean S, String tz, int radius) {
		this.hourlines = hrl;
		this.south = S;
		this.timezone = tz;
		this.length = radius;
		this.width = (int) (this.length*2.8);
		this.height = (int) (this.width*0.75);
		setBackground(Color.white);
		setPreferredSize(new Dimension(this.width, this.height));
	}
	/**
	 * paint the canvas with hour lines
	 */
	/* (non-Javadoc)
	 * @see javax.swing.JComponent#paint(java.awt.Graphics)
	 */
	@Override
	public void paint(Graphics canvas){
		super.paintComponent(canvas);
		// fancy hourlines marking
		String[] hours = {"VI", "", "VII", "", "VIII", "", "IX", "", "X", "", "XI", "", "XII", 
				"", "I", "", "II", "", "III", "", "IV", "", "V", "", "VI"};
		// draw the time zone of the user
    	canvas.setFont(new Font("Arial", Font.BOLD, 20));
    	canvas.drawString(this.timezone, (int)(this.width*0.4), (int)(this.height*0.1));
    	
    	int x1 = (int) (this.width*0.1), y1 = (int) (this.height*0.90), x2 = (int) (this.width*0.5), y2 = (int) (this.height*0.90);
		//lenth of the line
    	int length = x2-x1;
    	
    	//base of dial
    	canvas.drawLine(x1, y1, this.width - x1, y2);
		//draw the navigation indicator
		canvas.drawLine((int) (this.width*0.11), (int) (this.height*0.13), (int) (this.width*0.1), (int) (this.height*0.2));
		canvas.drawLine((int) (this.width*0.11), (int) (this.height*0.13), (int) (this.width*0.12), (int) (this.height*0.2));
		
		if(this.hourlines == null){
			//Should never execute, just safety net
			canvas.drawString("Hours array is null", this.width/2, this.height/2);
		}else if(!this.south){
			canvas.setFont(new Font("Arial", Font.BOLD, 30));
			//the direction user should face
			canvas.drawString("N", (int) (this.width*0.1), (int) (this.height*0.1));
			canvas.setFont(new Font("Arial", Font.PLAIN, 15));
			// double sunrise is use to indicate where is 30 mins mark
			double sunrise = 6;
			double degree;
			int tempX = 0, tempY = 0;
	        for(int i = 0; i < this.hourlines.length; i++){
	        	degree = (-this.hourlines[i]) * Math.PI/180;
	        	if(sunrise % 1 > 0){
	        		tempX = (int) (x2 - length*0.8 * Math.sin(degree));
	        		tempY = (int) (y2 - length*0.8 * Math.cos(degree));
	        	}
	        	else {
			     	tempX = (int) (x2 - length * Math.sin(degree));
			     	tempY = (int) (y2 - length * Math.cos(degree));
	        	}
		     	canvas.drawLine(tempX, tempY, x2, y2);
		     	canvas.drawString(hours[i], tempX, (int)(tempY*0.99));
		     	sunrise = sunrise + 0.5;
	        }
		}
		else {
			canvas.setFont(new Font("Arial", Font.BOLD, 30));
			//the direction user should face
			canvas.drawString("S", (int) (this.width*0.1), (int) (this.height*0.1));
			canvas.setFont(new Font("Arial", Font.PLAIN, 15));
			// double sunrise is use to indicate where is 30 mins mark
			double sunrise = 6;
			double degree;
			int tempX = 0, tempY = 0;
	        for(int i = 0; i < this.hourlines.length; i++){
	        	degree = (this.hourlines[i]) * Math.PI/180;
	        	if(sunrise % 1 > 0){
	        		tempX = (int) (x2 - length*0.8 * Math.sin(degree));
	        		tempY = (int) (y2 - length*0.8 * Math.cos(degree));
	        	}
	        	else {
			     	tempX = (int) (x2 - length * Math.sin(degree));
			     	tempY = (int) (y2 - length * Math.cos(degree));
	        	}
		     	canvas.drawLine(tempX, tempY, x2, y2);
		     	canvas.drawString(hours[i], tempX, (int)(tempY*0.99));
		     	sunrise = sunrise + 0.5;
	        }
		}
		//Vertical center line 
    	canvas.setColor(Color.red);
    	canvas.drawLine(x2,y1,x2,y1-length);
	}
	
	/* (non-Javadoc)
	 * @see java.awt.print.Printable#print(java.awt.Graphics, java.awt.print.PageFormat, int)
	 */
	@Override
	public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) {
		// number of page is zero based
        if (pageIndex > 0) {
            return NO_SUCH_PAGE;
        }

        // User (0,0) is typically outside the
        // imageable area, so we must translate
        // by the X and Y values in the PageFormat
        // to avoid clipping.
        Graphics2D g2d = (Graphics2D) graphics;
        g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

        // Now we perform our rendering
        //This prints a grey page with the applet name at the top, but no lines.
        //why no lines?
        this.paint(g2d);

        // tell the caller that this page is part
        // of the printed document
        return PAGE_EXISTS;
	}
}
